module OnlineStatsTest

using OnlineStats, StatsBase, QuadGK, Base.Test
import OnlineStatsBase

#-----------------------------------------------------------------------# helpers
function merge_vs_fit(o, y1, y2; kw...)
    s1 = series(y1, o; kw...)
    s2 = series(y2, copy(o); kw...)
    merge!(s1, s2)
    fit!(s2, y1)
    @test nobs(s1) == nobs(s2)
    first(stats(s1)), first(stats(s2))
end

# test: merge is same as fit!
function test_merge(o, y1, y2, compare = ≈)
    o1, o2 = merge_vs_fit(o, y1, y2)
    @test all(compare.(value(o1), value(o2)))
end

# test: fo(o) == fy(y)
function test_exact(o, y, fo, fy, compare = ≈)
    s = Series(y, o)
    @test all(compare.(fo(o), fy(y)))
end


#-----------------------------------------------------------------------# Data
const y = randn(100)
const y2 = randn(100)
const x = randn(100, 5)
const x2 = randn(100, 5)

#-----------------------------------------------------------------------# test files
include("test_show.jl")
include("test_series.jl")
include("test_stats.jl")
include("test_visualizations.jl")

println()
println()
info("Testing Everything else")
#-----------------------------------------------------------------------# OnlineStatsBase 
mutable struct Counter <: OnlineStatsBase.ExactStat{0}
    value::Int
    Counter() = new(0)
end
OnlineStatsBase._fit!(o::Counter, y::Real, w::Float64) = (o.value += 1)
@testset "OnlineStatsBase" begin 
    test_exact(Counter(), y, value, length)
end
#-----------------------------------------------------------------------# BiasVec
@testset "BiasVec" begin 
    v = rand(5)
    b = OnlineStats.BiasVec(v, 1.0)
    @test length(b) == 6 
    @test b == vcat(v, 1.0)
    @test size(b) == (6,)
    @test all(OnlineStats.BiasVec(v, 1.0) .== OnlineStats.BiasVec(v, 1))
    @test all(OnlineStats.BiasVec(v, 1.0) .== OnlineStats.BiasVec(v))
end
#-----------------------------------------------------------------------# mapblocks
@testset "mapblocks" begin 
    data = randn(10, 5)
    o = CovMatrix(5)
    s = Series(o)
    mapblocks(3, data, Rows()) do xi
        fit!(s, xi)
    end
    i = 0
    mapblocks(2, data, Cols()) do xi 
        i += 1
    end
    @test i == 3
    @test cov(o) ≈ cov(data)
    i = 0
    mapblocks(3, rand(5)) do xi
        i += 1
    end
    @test i == 2
    s = Series(LinReg(5))
    mapblocks(11, (x, y)) do xy
        fit!(s, xy)
    end
    @test value(s)[1] ≈ x\y
    @test_throws Exception mapblocks(info, (randn(100,5), randn(3)))
    @test_throws Exception OnlineStats._nobs((randn(100,5), randn(3)), Cols())
end
end #module
